﻿using System;
using System.Windows.Controls;
using System.Windows.Markup;
using ICodeShare.UI.Converters.Extensions;

namespace ICodeShare.UI.Converters.Markup
{
    #region MarkupExtension
    /// <summary>
    /// 实现一个扩展标记用来实例化CharacterCasingConverter
    /// </summary>
    /// <example>
    /// 1.在xmal文件引用DateConverter类所在命名空间。
    ///    xmlns:cvts="http://schemas.extended.wpf.com/converters"
    /// 2.在xaml文件中指定Binding值的Converter
    ///    <Label Content="{Binding Name, Converter={cvts:CharacterCasingConverter}}"/>
    ///    <Label Content="{Binding Name, Converter={cvts:CharacterCasingConverter Normal}}"/>
    ///    <Label Content="{Binding Name, Converter={cvts:CharacterCasingConverter Upper}}"/>
    ///    <Label Content="{Binding Name, Converter={cvts:CharacterCasingConverter Lower}}"/>
    ///    <Label Content="{Binding Name, Converter={cvts:CharacterCasingConverter SourceCasing=Upper, TargetCasing=Lower},Mode=TwoWay}"/>
    /// </example>
    /// <remarks>
    /// 
    /// </remarks>
    [MarkupExtensionReturnType(typeof(CharacterCasingConverter))]
    public sealed class CharacterCasingConverterExtension : MarkupExtension
    {
        private CharacterCasing sourceCasing;
        private CharacterCasing targetCasing;

        /// <summary>
        /// Initializes a new instance of the CaseConverterExtension class.
        /// </summary>
        public CharacterCasingConverterExtension()
        {
        }

        /// <summary>
        /// Initializes a new instance of the CaseConverterExtension class with the specified <see cref="Casing"/>.
        /// </summary>
        /// <param name="casing">
        /// The casing for the <see cref="CaseConverter"/>.
        /// </param>
        public CharacterCasingConverterExtension(CharacterCasing casing)
        {
            this.Casing = casing;
        }

        /// <summary>
        /// Initializes a new instance of the CaseConverterExtension class with the specified source and target <see cref="Casing"/>.
        /// </summary>
        /// <param name="sourceCasing">
        /// The source casing for the <see cref="CaseConverter"/>.
        /// </param>
        /// <param name="targetCasing">
        /// The target casing for the <see cref="CaseConverter"/>.
        /// </param>
        public CharacterCasingConverterExtension(CharacterCasing sourceCasing, CharacterCasing targetCasing)
        {
            this.SourceCasing = sourceCasing;
            this.TargetCasing = targetCasing;
        }

        /// <summary>
        /// Gets or sets the source <see cref="CharacterCasing"/> for the <see cref="CaseConverter"/>.
        /// </summary>
        [ConstructorArgument("sourceCasing")]
        public CharacterCasing SourceCasing
        {
            get
            {
                return this.sourceCasing;
            }

            set
            {
                value.AssertEnumMember("value", CharacterCasing.Lower, CharacterCasing.Normal, CharacterCasing.Upper);
                this.sourceCasing = value;
            }
        }

        /// <summary>
        /// Gets or sets the target <see cref="CharacterCasing"/> for the <see cref="CaseConverter"/>.
        /// </summary>
        [ConstructorArgument("targetCasing")]
        public CharacterCasing TargetCasing
        {
            get
            {
                return this.targetCasing;
            }

            set
            {
                value.AssertEnumMember("value", CharacterCasing.Lower, CharacterCasing.Normal, CharacterCasing.Upper);
                this.targetCasing = value;
            }
        }

        /// <summary>
        /// Sets both the source and target <see cref="CharacterCasing"/> for the <see cref="CaseConverter"/>.
        /// </summary>
        public CharacterCasing Casing
        {
            set
            {
                value.AssertEnumMember("value", CharacterCasing.Lower, CharacterCasing.Normal, CharacterCasing.Upper);
                this.sourceCasing = value;
                this.targetCasing = value;
            }
        }

        /// <summary>
        /// Provides an instance of <see cref="CaseConverter"/> based on <see cref="SourceCasing"/> and <see cref="TargetCasing"/>.
        /// </summary>
        /// <param name="serviceProvider">
        /// An object that can provide services.
        /// </param>
        /// <returns>
        /// The instance of <see cref="CaseConverter"/>.
        /// </returns>
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return new CharacterCasingConverter(this.SourceCasing, this.TargetCasing);
        }
    }
    #endregion
}
